home *** CD-ROM | disk | FTP | other *** search
/ Openstep 4.2 (Developer) / Openstep Developer 4.2.iso / NextDeveloper / Source / GNU / uucp / Uucp.framework / unix.subproj / recep.c < prev    next >
Encoding:
C/C++ Source or Header  |  1995-10-09  |  5.5 KB  |  202 lines

  1. /* recep.c
  2.    See whether a file has already been received.
  3.  
  4.    Copyright (C) 1992, 1993, 1995 Ian Lance Taylor
  5.  
  6.    This file is part of the Taylor UUCP package.
  7.  
  8.    This program is free software; you can redistribute it and/or
  9.    modify it under the terms of the GNU General Public License as
  10.    published by the Free Software Foundation; either version 2 of the
  11.    License, or (at your option) any later version.
  12.  
  13.    This program is distributed in the hope that it will be useful, but
  14.    WITHOUT ANY WARRANTY; without even the implied warranty of
  15.    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16.    General Public License for more details.
  17.  
  18.    You should have received a copy of the GNU General Public License
  19.    along with this program; if not, write to the Free Software
  20.    Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.
  21.  
  22.    The author of the program may be contacted at ian@airs.com or
  23.    c/o Cygnus Support, 48 Grove Street, Somerville, MA 02144.
  24.    */
  25.  
  26. #include "uucp.h"
  27.  
  28. #include "uudefs.h"
  29. #include "uuconf.h"
  30. #include "sysdep.h"
  31. #include "system.h"
  32.  
  33. #include <errno.h>
  34.  
  35. #if HAVE_TIME_H
  36. #include <time.h>
  37. #endif
  38.  
  39. #if HAVE_FCNTL_H
  40. #include <fcntl.h>
  41. #else
  42. #if HAVE_SYS_FILE_H
  43. #include <sys/file.h>
  44. #endif
  45. #endif
  46.  
  47. static char *zsreceived_name P((const struct uuconf_system *qsys,
  48.                 const char *ztemp));
  49.  
  50. /* These routines are used to see whether we have already received a
  51.    file in a previous UUCP connection.  It is possible for the
  52.    acknowledgement of a received file to be lost.  The sending system
  53.    will then not know that the file was correctly received, and will
  54.    send it again.  This can be a problem particularly with protocols
  55.    which support channels, since they may send several small files in
  56.    a single window, all of which may be received correctly although
  57.    the sending system never sees the acknowledgement.  If these files
  58.    involve an execution, the execution will happen twice, which will
  59.    be bad.
  60.  
  61.    We use a simple system.  For each file we want to remember, we
  62.    create an empty file names .Received/SYS/TEMP, where SYS is the
  63.    name of the system and TEMP is the name of the temporary file used
  64.    by the sender.  If no temporary file is used by the sender, we
  65.    don't remember that we received the file.  This is not perfect, but
  66.    execution files will always have a temporary file, so the most
  67.    important case is handled.  Also, any file received from Taylor
  68.    UUCP 1.04 or greater will always have a temporary file.  */
  69.  
  70. /* Return the name we are going use for the marker, or NULL if we have
  71.    no name.  */
  72.  
  73. static char *
  74. zsreceived_name (qsys, ztemp)
  75.      const struct uuconf_system *qsys;
  76.      const char *ztemp;
  77. {
  78.   if (ztemp != NULL
  79.       && *ztemp == 'D'
  80.       && strcmp (ztemp, "D.0") != 0)
  81.     return zsappend3 (".Received", qsys->uuconf_zname, ztemp);
  82.   else
  83.     return NULL;
  84. }
  85.  
  86. /* Remember that we have already received a file.  */
  87.  
  88. /*ARGSUSED*/
  89. boolean
  90. fsysdep_remember_reception (qsys, zto, ztemp)
  91.      const struct uuconf_system *qsys;
  92.      const char *zto;
  93.      const char *ztemp;
  94. {
  95.   char *zfile;
  96.   int o;
  97.  
  98.   zfile = zsreceived_name (qsys, ztemp);
  99.   if (zfile == NULL)
  100.     return TRUE;
  101.   o = creat (zfile, IPUBLIC_FILE_MODE);
  102.   if (o < 0)
  103.     {
  104.       if (errno == ENOENT)
  105.     {
  106.       if (fsysdep_make_dirs (zfile, FALSE))
  107.         {
  108.           ubuffree (zfile);
  109.           return FALSE;
  110.         }
  111.       o = creat (zfile, IPUBLIC_FILE_MODE);
  112.     }
  113.       if (o < 0)
  114.     {
  115.       ulog (LOG_ERROR, "creat (%s): %s", zfile, strerror (errno));
  116.       ubuffree (zfile);
  117.       return FALSE;
  118.     }
  119.     }
  120.  
  121.   ubuffree (zfile);
  122.  
  123.   /* We don't have to actually put anything in the file; we just use
  124.      the name.  This is more convenient than keeping a file with a
  125.      list of names.  */
  126.   if (close (o) < 0)
  127.     {
  128.       ulog (LOG_ERROR, "fsysdep_remember_reception: close: %s",
  129.         strerror (errno));
  130.       return FALSE;
  131.     }
  132.  
  133.   return TRUE;
  134. }
  135.  
  136. /* The number of seconds in one week.  We must cast to long for this
  137.    to be calculated correctly on a machine with 16 bit ints.  */
  138. #define SECS_PER_WEEK ((long) 7 * (long) 24 * (long) 60 * (long) 60)
  139.  
  140. /* See if we have already received a file.  Note that don't delete the
  141.    marker file here, because we need to know that the sending system
  142.    has received our denial first.  This function returns TRUE if the
  143.    file has already been received, FALSE if it has not.  */
  144.  
  145. /*ARGSUSED*/
  146. boolean
  147. fsysdep_already_received (qsys, zto, ztemp)
  148.      const struct uuconf_system *qsys;
  149.      const char *zto;
  150.      const char *ztemp;
  151. {
  152.   char *zfile;
  153.   struct stat s;
  154.   boolean fret;
  155.  
  156.   zfile = zsreceived_name (qsys, ztemp);
  157.   if (zfile == NULL)
  158.     return FALSE;
  159.   if (stat (zfile, &s) < 0)
  160.     {
  161.       if (errno != ENOENT)
  162.     ulog (LOG_ERROR, "stat (%s): %s", zfile, strerror (errno));
  163.       ubuffree (zfile);
  164.       return FALSE;
  165.     }
  166.  
  167.   /* Ignore the file (return FALSE) if it is over one week old.  */
  168.   fret = s.st_mtime + SECS_PER_WEEK >= time ((time_t *) NULL);
  169.  
  170.   if (fret)
  171.     DEBUG_MESSAGE1 (DEBUG_SPOOLDIR, "fsysdep_already_received: Found %s",
  172.             zfile);
  173.  
  174.   ubuffree (zfile);
  175.  
  176.   return fret;
  177. }
  178.  
  179. /* Forget that we have received a file.  */
  180.  
  181. /*ARGSUSED*/
  182. boolean
  183. fsysdep_forget_reception (qsys, zto, ztemp)
  184.      const struct uuconf_system *qsys;
  185.      const char *zto;
  186.      const char *ztemp;
  187. {
  188.   char *zfile;
  189.  
  190.   zfile = zsreceived_name (qsys, ztemp);
  191.   if (zfile == NULL)
  192.     return TRUE;
  193.   if (remove (zfile) < 0
  194.       && errno != ENOENT)
  195.     {
  196.       ulog (LOG_ERROR, "remove (%s): %s", zfile, strerror (errno));
  197.       ubuffree (zfile);
  198.       return FALSE;
  199.     }
  200.   return TRUE;
  201. }
  202.